package co.gov.medellin.ssti.sub.paoyer.administration.dao;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.sql.PreparedStatement;

import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.OptionVO;

/**
 * DAO para crear, consultar y actualizar registros en la tabla TCS_OPCION.
 * 
 * @author Rene.Rangel@consultsoft.com
 * @version 1.0
 */

public class OptionDAO {
	/**
	 * Conexion a la base de datos.
	 */
	private Connection conn = null;

	/**
	 * Constructor que inicializa la conexion con la base de datos.
	 * 
	 * @param conn
	 *            Conexion con la base de datos.
	 */

	public OptionDAO(Connection conn) {
		this.conn = conn;
	}

	/**
	 * Consulta un grupo de registros de la tabla TCS_OPCION a partir de las
	 * condiciones que vienen en el Value Object
	 * 
	 * @param OptionVO
	 *            Value Object con las condiciones a tener encuenta.
	 * 
	 * @return Collection Arreglo de registros retornados de la consulta.
	 */
	public Collection<OptionVO> findOptionByCriterea(OptionVO criterea)
			throws SQLException {

		/**
		 * Aqui en la busqueda se cruza dos veces la tabla Tcs_Opcion y tambien
		 * se cruza la tabla TCS_PROGRAMA con el objeto de retornar el nombre de
		 * la opcion padre y del programa asociado a la opcion
		 */

		String query = "SELECT opci.*, opc2.nombre opcion_padre,  prog.nombre programa "
				+ "FROM tcs_opcion opci, tcs_opcion opc2, tcs_programa prog ";

		String filters = "";
		// Filtro por Nombre
		if ((criterea.getName() != null) && !(criterea.getName().equals(""))) {
			filters = filters + "AND UPPER(opci.nombre) LIKE '%"
					+ criterea.getName().toUpperCase() + "%' ";
		}

		/*
		 * / // Filtro por Descripcion if ( (criterea.getDescription() != null)
		 * && !(criterea.getDescription().equalsIgnoreCase("")) ) { filters =
		 * filters + " AND UPPER(opci.descripcion) LIKE '%" +
		 * criterea.getDescription().toUpperCase() + "%' "; }
		 * 
		 * 
		 * 
		 * // Filtro por Parametros de la Opcion if ( (criterea.getParameters()
		 * != null) && !(criterea.getParameters().equals("")) ) { filters =
		 * filters + " AND opci.parameters = '" + criterea.getParameters()+"'";
		 * }
		 */

		// Filtro por Tipo Opcion
		if ((criterea.getOptionType() != null)
				&& !(criterea.getOptionType().equals(""))) {
			filters = filters + " AND opci.tipo_opcion = '"
					+ criterea.getOptionType() + "'";
		}

		/*
		 * // Filtro por Orden if (criterea.getOrder() != null &&
		 * !(criterea.getOrder().longValue() == 0) ) { filters = filters +
		 * " AND opci.orden =" + criterea.getOrder(); }
		 */
		// Filtro por Codigo
		if (criterea.getCode() != null
				&& !(criterea.getCode().longValue() == 0)) {
			filters = filters + " AND opci.codigo =" + criterea.getCode();
		}

		/*
		 * // Filtro por Icono if ( (criterea.getIcon() != null) &&
		 * !(criterea.getIcon().equals("")) ) { filters = filters +
		 * " AND opci.icono = '" + criterea.getIcon()+"'"; }
		 * 
		 * // Filtro por Option Padre if (criterea.getOptionCode() != null &&
		 * !(criterea.getOptionCode().intValue() == 0)) { filters = filters +
		 * " AND opci.opc_codigo =" + criterea.getOptionCode(); }
		 * 
		 * // Filtro por Programa Asociado if (criterea.getProgramCode() != null
		 * && !(criterea.getProgramCode().intValue() == 0)) { filters = filters
		 * + " AND opci.prg_codigo =" + criterea.getProgramCode(); }
		 */

		query = query
				+ " WHERE prog.codigo(+) = opci.prg_codigo AND opc2.codigo(+) = opci.opc_codigo  "
				+ " and prog.tipo_progr = 'U' ";
		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + filters;
		}
		Statement stm = null;
		ResultSet rst = null;
		ArrayList<OptionVO> options = new ArrayList<OptionVO>();

		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			OptionVO option = new OptionVO();
			option.setCode(new Long(rst.getLong("codigo")));
			option.setName(rst.getString("nombre"));
			option.setDescription(rst.getString("descripcion"));
			option.setWebUserCrea(rst.getString("usuario_crea"));
			option.setWebClientCrea(rst.getString("terminal_crea"));
			option.setWebUserModif(rst.getString("usuario_modifica"));
			option.setWebClientModif(rst.getString("terminal_modifica"));
			option.setParameters(rst.getString("parametros"));
			option.setOptionType(rst.getString("tipo_opcion"));
			option.setOrder(new Long(rst.getLong("orden")));
			option.setIcon(rst.getString("icono"));
			option.setOptionCode(new Long(rst.getLong("opc_codigo")));
			option.setProgramCode(new Long(rst.getLong("prg_codigo")));
			option.setFatherOptionName(rst.getString("opcion_padre"));
			option.setParentProgramName(rst.getString("programa"));
			options.add(option);
		}

		stm.close();

		return options;
	}

	/**
	 * Crea un nuevo registro en la tabla TCS_OPCION.
	 * 
	 * @param OptionVO
	 *            Value Object con el registro que se va a Crear.
	 * 
	 * @return OptionVO Registro creado.
	 * 
	 */
	public OptionVO createOption(OptionVO newOption) throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = ""
				+ "INSERT INTO tcs_opcion ("
				+ "            codigo, nombre, descripcion, usuario_crea, terminal_crea, "
				+ "            usuario_modifica, terminal_modifica,  "
				+ "            tipo_opcion, orden, opc_codigo, prg_codigo) "
				+ "VALUES(scs_opcion.NEXTVAL,?,?,?,?,?,?,?,?,?,?)";

		ps = conn.prepareStatement(strSQL);
		ps.setString(1, newOption.getName().toUpperCase());
		ps.setString(2, newOption.getDescription().toUpperCase());
		ps.setString(3, newOption.getWebUserCrea().toUpperCase());
		ps.setString(4, "WEB=" + newOption.getWebClientCrea().toUpperCase());
		ps.setString(5, newOption.getWebUserModif().toUpperCase());
		ps.setString(6, "WEB=" + newOption.getWebClientModif().toUpperCase());
		// ps.setString(7, newOption.getParameters().toUpperCase());
		ps.setString(7, newOption.getOptionType().toUpperCase());
		ps.setLong(8, newOption.getOrder().longValue());
		if (newOption.getOptionCode() != null) {
			ps.setLong(9, newOption.getOptionCode().longValue());
		} else {
			ps.setNull(9, Types.NUMERIC);
		}
		if (newOption.getProgramCode() != null) {
			ps.setLong(10, newOption.getProgramCode().longValue());
		} else {
			ps.setNull(10, Types.NUMERIC);
		}

		result = ps.execute();
		ps.close();

		return newOption;
	}

	/**
	 * Actualiza un registro en la tabla TCS_OPCION por la llave primaria.
	 * 
	 * @param OptionVO
	 *            Value Object con el registro que se va a modificar.
	 * 
	 * @return OptionVO Registro modificado.
	 * 
	 */
	public OptionVO updateOption(OptionVO option) throws SQLException {

		String strSQL = "UPDATE tcs_opcion " + "SET nombre = ?, "
				+ "descripcion = ?, " + "usuario_modifica = ?, "
				+ "terminal_modifica = ?, "
				+
				// "parametros = ?, " +
				"tipo_opcion = ?, " + "orden = ?, " + "opc_codigo = ?, "
				+ "prg_codigo = ? " + "WHERE codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);

		ps.setString(1, option.getName().toUpperCase());
		ps.setString(2, option.getDescription().toUpperCase());
		ps.setString(3, option.getWebUserModif().toUpperCase());
		ps.setString(4, "WEB=" + option.getWebClientModif().toUpperCase());
		// ps.setString(5, option.getParameters().toUpperCase());
		ps.setString(5, option.getOptionType().toUpperCase());
		ps.setLong(6, option.getOrder().longValue());
		if (option.getOptionCode() != null) {
			ps.setLong(7, option.getOptionCode().longValue());
		} else {
			ps.setNull(7, Types.NUMERIC);
		}
		if (option.getProgramCode() != null) {
			ps.setLong(8, option.getProgramCode().longValue());
		} else {
			ps.setNull(8, Types.NUMERIC);
		}

		ps.setLong(9, option.getCode().longValue());

		int updates = ps.executeUpdate();

		if (updates == 0) {
			return null;
		}

		ps.close();

		return option;

	}

	/**
	 * Borra un registro de la tabla TCS_OPCION por la llave primaria.
	 * 
	 * @param OptionVO
	 *            Value Object con el registro que se va a borrar.
	 * 
	 * @return boolean Indicador de exito de la operacion de borrado
	 */
	public boolean deleteOption(OptionVO option) throws SQLException {

		String strSQL = "DELETE from tcs_opcion " + "WHERE  codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setLong(1, option.getCode().longValue());
		boolean deletes = ps.execute();
		ps.close();
		return deletes;
	}

}